Hammerspoon CLI script
- 2025-04-18
A Hammerspoon script that, when you select text and input a shell command, executes the command by piping the selected text into standard input and copies the standard output to the clipboard.
For example, if you select a specific column in Google Sheets and enter grep "X" | sort | uniq
, the result of filtering cells containing X, then sorting, and removing duplicates will be copied to the clipboard.
Code
local os = require("os")
local obj = {}
function obj:init()
self.statusIcon = hs.menubar.new()
return self
end
function obj:setStatus(emoji)
self.statusIcon:setTitle(emoji)
end
function obj:clearStatus()
self.statusIcon:setTitle("")
end
function obj:bindHotkeys(mapping)
local spec = { run = hs.fnutils.partial(self.run, self) }
hs.spoons.bindHotkeysToSpec(spec, mapping)
return self
end
function obj:run()
-- Copy the text to the clipboard
hs.eventtap.keyStroke({ "cmd" }, "c")
hs.timer.usleep(0.001)
-- Get the text from the clipboard
local input = hs.pasteboard.getContents()
if input == nil then
hs.alert("Please select the text first")
return
end
-- Get the command
local cmd = self:getCommand()
if cmd == nil then
return
end
-- Run the command
self:setStatus("⏳")
hs.task.new(os.getenv("SHELL"), function(code, out, err)
if code ~= 0 then
hs.dialog.blockAlert("Error", err, "Ok")
else
hs.alert("Updated clipboard")
end
self:clearStatus()
end, {
"-i", "-c", "pbpaste | " .. cmd .. " | pbcopy"
}):start()
end
function obj:getCommand()
local focusedApp = hs.window.frontmostWindow():application()
local button, userInput = hs.dialog.textPrompt("Enter the command", "", "llm \"Summerize\"", "Ok", "Cancel")
if focusedApp then
hs.timer.doAfter(0.01, function()
focusedApp:activate()
end)
end
if button == "Ok" then
return userInput
else
return nil
end
end
return obj